﻿using AutoMapper.Configuration.Conventions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.VisualBasic.FileIO;
using Polly;
using VM.Common.DataUntil;
using VM.Common.Result;
using VM.Entity.EntityMap.Files;
using VM.IBLL.Files;
using VM.IBLL.Member;
using VM.WebCore.Jwt;
using VM.Wechat;

namespace VM.WebAPI.Controllers
{
    /// <summary>
    /// 文件处理相关操作类
    /// </summary>
    [Route("api/files")]
    [ApiController]
    public class FilesController : ControllerBase
    { 
        private readonly IJWTService _IJWTService;
        private readonly IHttpContextAccessor _HttpContextAccessor;
        private readonly IFilesBLL _IFilesBLL;

        public FilesController(IJWTService iJWTService,   IHttpContextAccessor httpContextAccessor, IFilesBLL iFilesBLL)
        {
            _IJWTService = iJWTService;
            _HttpContextAccessor = httpContextAccessor;
            _IFilesBLL = iFilesBLL;
        }
        /// <summary>
        /// 文件上传    PC+PHONE   
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]//要求通过授权才行---只要能鉴权成功，都能通过]
        [Route("Upload")]
        public async Task<ApiDataResult<Entity.EntityMap.Files.FileInfo>> Upload([FromForm]FileUpload obj)
        {
            try
            {
                //获取今日日期字符串
                string DateStr = DateTime.Now.ToString("yyyyMMdd");
                string Basepath = AppDomain.CurrentDomain.BaseDirectory;

                //判断用户是否已注册
                //获取到header 内的用户信息进行解析
                var authorizationHeader = _HttpContextAccessor.HttpContext.Request.Headers["Authorization"];
                //解析jwt
                string tokenInfo = authorizationHeader.ToString().Replace("bearer ", "").Replace("Bearer ", "");
                var AESId = _IJWTService.AnaliseToken(tokenInfo, "id");
                //解析userid
                string memberId = AESUntil.Decrypt(AESId);
                string OldFileName = obj.file.FileName;
                //获取文件的后缀名
                string SaveName = Timestamp.getNowTimeStamp().ToString() + RandomNo.GetRandomNo6().ToString() + memberId+obj.file.FileName;
                 long  size = obj.file.Length;
                if (obj.file == null || obj.file.Length == 0)
                {
                    return new ApiDataResult<Entity.EntityMap.Files.FileInfo>
                    {
                        code = 403,
                        msg = "上传失败:文件为空" ,
                        data = null
                    };
                }
                string SaveParamPath = $@"Upload/" + DateStr +"/"+ SaveName;
                var uploadsRootFolder = Path.Combine(Basepath, $@"Upload/" + DateStr);
                if (!Directory.Exists(uploadsRootFolder))
                    Directory.CreateDirectory(uploadsRootFolder);
                var filePath = Path.Combine(uploadsRootFolder, SaveName);
                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await obj.file.CopyToAsync(stream);
                }
                Entity.EntityMap.Files.FileInfo fileRes = new Entity.EntityMap.Files.FileInfo();
                fileRes.newFileName = SaveName;
                fileRes.size=size;
                fileRes.savePath = SaveParamPath;
                fileRes.fileName = OldFileName;
                #region 无用
                ////处理记录信息
                //sys_fileLog sys_FileLog = new sys_fileLog()
                //{
                //    createUserId =Convert.ToInt32( memberId),
                //    createDate=DateTime.Now,
                //    isDelete=0,
                //    oldFileName=OldFileName,
                //    fileName=SaveName,
                //    filePath=filePath,
                //    businessName=obj.businessName,
                //    menuId=obj.menuId,
                //    fileType=obj.fileType,
                //    roleInfoIds="",
                //    description="上传文件后自动添加",
                //    size=obj.file.Length

                //};
                //_IFilesBLL.addFileRecordBLL(sys_FileLog,Convert.ToInt32(memberId));
                #endregion
                return new ApiDataResult<Entity.EntityMap.Files.FileInfo>
                {
                    code = 200,
                    msg = "上传成功",
                    data = fileRes
                }; 
            }
            catch (Exception ex)
            {
                return new ApiDataResult<Entity.EntityMap.Files.FileInfo>
                {
                    code = 403,
                    msg = "上传失败"+ ex.Message,
                    data = null
                };
                
            }

        }

        /// <summary>
        /// 批量保存文件上传记录，这个一般用不到，大多数的文件上传记录在业务内自动处理了
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]//要求通过授权才行---只要能鉴权成功，都能通过]
        [Route("addFileRecords")]
        public async Task<ApiDataResult<int>> addFileRecords(batchfilesLog obj)
        {
            ApiDataResult<sys_fileLog> res = new ApiDataResult<sys_fileLog>();
            try
            { 
                 //获取到header 内的用户信息进行解析
                 var authorizationHeader = _HttpContextAccessor.HttpContext.Request.Headers["Authorization"];
                //解析jwt
                string tokenInfo = authorizationHeader.ToString().Replace("bearer ", "").Replace("Bearer ", "");
                var AESId = _IJWTService.AnaliseToken(tokenInfo, "id");
                //解析userid
                int  memberId = Convert.ToInt32( AESUntil.Decrypt(AESId));
                ApiDataResult<int> sysFileLogRes =new ApiDataResult<int>();
                
               sysFileLogRes = _IFilesBLL.batchAddFileRecordBLL(obj, memberId);

                return sysFileLogRes;
                  
            }
            catch (Exception ex)
            {
                return new ApiDataResult<int>
                {
                    code = 403,
                    msg = "错误:"+ex.Message,
                    data = 0
                };

            }

        }

        







        /// <summary>
        /// 大文件拆分上传 
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]//要求通过授权才行---只要能鉴权成功，都能通过]
        [Route("splitUpload")]
        public async Task<IActionResult> splitUpload([FromQuery] SliceFileInfo file)
        {
            try
            {
                string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Upload");

                var files = Request.Form.Files;
                var buffer = new byte[file.Size];
                var fileName = file.Name;
                path = path + "//" + fileName + "//";
                if (!System.IO.Directory.Exists(path))
                {
                    System.IO.Directory.CreateDirectory(path);
                }
                string filepath = path + "//" + file.Name + "^" + file.Number;
                using (var stream = new FileStream(filepath, FileMode.Append))
                {
                    await files[0].CopyToAsync(stream);
                }
                var filesList = Directory.GetFiles(Path.GetDirectoryName(path));

                //当顺序号等于分片总数量 合并文件
                if ((file.Number + 1) == file.Count || filesList.Length == file.Count)
                {

                    await MergeFile(file);
                }
                return this.Ok();

            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }

        }
        /// <summary>
        /// 合并文件
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        private async Task MergeFile(SliceFileInfo file)
        {
            string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Upload");
            var fileName = file.Name;
            path = path + "//" + fileName + "//";
            string baseFileName = path + fileName.Split("~")[0].ToString();
            if (!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }
            var filesList = Directory.GetFiles(Path.GetDirectoryName(path));
            if (filesList.Length != file.Count)
            {
                return;
            }
            List<FileSort> lstFile = new List<FileSort>();
            foreach (var item in filesList)
            {
                lstFile.Add(new FileSort()
                {
                    Name = item,
                    NumBer = Convert.ToInt32(item.Substring(item.IndexOf('^') + 1))
                });
            }
            lstFile = lstFile.OrderBy(x => x.NumBer).ToList();
            using (var fileStream = new FileStream(baseFileName, FileMode.Create))
            {
                //foreach (var fileSort in filesList)
                //{
                // using (FileStream fileChunk = new FileStream(fileSort, FileMode.Open))
                // {
                // await fileChunk.CopyToAsync(fileStream);
                // }

                //}
                await Policy.Handle<IOException>()
                .RetryForeverAsync()
                .ExecuteAsync(async () =>
                {
                    foreach (var fileSort in lstFile)
                    {
                        using (FileStream fileChunk = new FileStream(fileSort.Name, FileMode.Open))
                        {
                            await fileChunk.CopyToAsync(fileStream);
                        }

                    }
                });


            }
            //删除分片文件
            foreach (var dirfile in filesList)
            {
                System.IO.File.Delete(dirfile);
            }
        }
    }
}
